package VideoTools;

import java.awt.AWTException;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.LinkedList;

import UI.Window;

import dimension2.Circle;

public class Movement implements Runnable {

	public enum ModeSimulation {KEYBOARD,MOUSE,BOTH,NONE}
	private static final double InvariantX = 10;
	private static final double InvariantY = 10;
	private static final int nbPosSameRegionToDoAClick = 100;
	public static ModeSimulation mode=ModeSimulation.KEYBOARD;
	private static int speed;
	private static Direction direction;
    
	private static int cpt = 0;
	
	public LinkedList<Point> waitingList = new LinkedList<Point>();
	public Point dernier;
	private boolean stateThread=false;
	
	public static int NB_FRAME_FOR_ONE_SIMULATION=10;
	public static int SIMULATION_KEY_UP_1 = KeyEvent.VK_UP;
	public static int SIMULATION_KEY_UP_2 = KeyEvent.VK_8;
	public static int SIMULATION_KEY_DOWN_1 = KeyEvent.VK_DOWN; 
	public static int SIMULATION_KEY_DOWN_2 = KeyEvent.VK_2;
	public static int SIMULATION_KEY_RIGHT_1 = KeyEvent.VK_RIGHT;
	public static int SIMULATION_KEY_RIGHT_2 = KeyEvent.VK_6;
	public static int SIMULATION_KEY_LEFT_1 = KeyEvent.VK_LEFT;
	public static int SIMULATION_KEY_LEFT_2 = KeyEvent.VK_4;
	public static int SIMULATION_KEY_UPRIGHT_1 = KeyEvent.VK_7;
	public static int SIMULATION_KEY_UPRIGHT_2 = -1;
	public static int SIMULATION_KEY_DOWNRIGHT_1 = KeyEvent.VK_1;
	public static int SIMULATION_KEY_DOWNRIGHT_2 = -1;
	public static int SIMULATION_KEY_DOWNLEFT_1 = KeyEvent.VK_3;
	public static int SIMULATION_KEY_DOWNLEFT_2 = -1;
	public static int SIMULATION_KEY_UPLEFT_1 = KeyEvent.VK_9;
	public static int SIMULATION_KEY_UPLEFT_2 = -1;
	
    
    public Movement() {
    	Movement.speed=0;
    	Movement.direction=Direction.ANY;
    }

    public void set(int speed,Direction direction){
    	Movement.direction=direction;
    }
	
    public Direction getDirection() {
		return direction;
	}
	public void setDirection(Direction direction) {
		this.direction = direction;
	}
	public int getSpeed() {
		return speed;
	}
	public void setSpeed(int speed) {
		this.speed = speed;
	} 
	
	public String toString(){
		return "speed : " + speed + ", direction : " + direction;
	}
	
	
	public void simulation(Circle c) throws SimulationException{
		switch(mode){
		case KEYBOARD:simulationKeyboard();break;
		case MOUSE:simulationMouse(c);break;
		case BOTH:simulationKeyboard();simulationMouse(c);break;
		case NONE:;break;
		}
	}
	

	/**
	 * simulation of the keyboard with Robot class
	 * @throws SimulationException 
	 */
	public void simulationKeyboard() throws SimulationException {
		 cpt++;
		if (cpt%NB_FRAME_FOR_ONE_SIMULATION==0){
			try {
				Robot robot = new Robot();
				
				switch (direction){
				
				case UP:robot.keyPress(SIMULATION_KEY_UP_1);robot.keyPress(SIMULATION_KEY_UP_2);break;
				case DOWN:robot.keyPress(SIMULATION_KEY_DOWN_1);robot.keyPress(SIMULATION_KEY_DOWN_2);break;
				case LEFT:robot.keyPress(SIMULATION_KEY_RIGHT_1);robot.keyPress(SIMULATION_KEY_RIGHT_2);break;
				case RIGHT:robot.keyPress(SIMULATION_KEY_LEFT_1);robot.keyPress(SIMULATION_KEY_LEFT_2);break;
				case UPRIGHT:robot.keyPress(SIMULATION_KEY_UPRIGHT_1);robot.keyPress(SIMULATION_KEY_UPRIGHT_2);break;
				case DOWNRIGHT:robot.keyPress(SIMULATION_KEY_DOWNRIGHT_1);robot.keyPress(SIMULATION_KEY_DOWNRIGHT_2);break;
				case UPLEFT:robot.keyPress(SIMULATION_KEY_UPLEFT_1);robot.keyPress(SIMULATION_KEY_UPLEFT_2);break;
				case DOWNLEFT:robot.keyPress(SIMULATION_KEY_DOWNLEFT_1);robot.keyPress(SIMULATION_KEY_DOWNLEFT_2);break;
				
				}
				
			} catch (AWTException e) {
				throw new SimulationException(e.getMessage());
			}
			catch (IllegalArgumentException i){
				System.out.println("rien faire");
			}
		}

	}
	
	
	public void simulationMouse(Circle c) {
		/*
		try {
			Robot robot = new Robot();
			if (c!=null)
			robot.mouseMove((int)(c.getCenter().getX()*(Window.dimensionScreen.getWidth()/VideoPlayer.size_X)), (int)(c.getCenter().getY()*(Window.dimensionScreen.getHeight()/VideoPlayer.size_Y)));
		} catch (AWTException e) {
			throw new SimulationException(e.getMessage());
		}
		*/
		if (!stateThread)(new Thread(this)).start();
		if (c!=null){
			Point last = new Point((int)(c.getCenter().getX()*(Window.dimensionScreen.getWidth()/VideoPlayer.size_X)),(int)(c.getCenter().getY()*(Window.dimensionScreen.getHeight()/VideoPlayer.size_Y)));
			// demmarage 
			if (dernier==null)dernier=last;
			
			// si il n'y a pas trop de difference en X et Y entre le dernier et l'ancien
			if (Math.abs(dernier.getX()-last.getX())<InvariantX && Math.abs(dernier.getY()-last.getY())<InvariantY){
				System.out.println("meme point");
			}
			else {
//				// si c'est different, on ajoute un point entre le dernier et l'avant dernier.
				System.out.println(dernier);
				System.out.println(last);
				Point nouveausur2 = new Point((int)(dernier.getX()+(last.getX()-dernier.getX())/2),(int)(dernier.getY()+(last.getY()-dernier.getY())/2));
				System.out.println(nouveausur2);
				waitingList.addFirst(nouveausur2);
				dernier=last; 
				System.out.println("pas meme point");
			}
			waitingList.addFirst(dernier);
			
		}
	}

	
	

	public void run() {
		try {
			Robot robot = new Robot();
			int compteur=0;
			int x=0,y=0;
			for(;;){
				stateThread=true;
				
				// on ne vide pas totalement la liste, on garde le dernier
				while (waitingList.size()!=0){
					Point p =waitingList.removeLast();
					
					if ((int)p.getX()==x && (int)p.getY()==y){
						System.out.println(compteur);
						compteur++;
					}
					
					if (compteur == nbPosSameRegionToDoAClick){
						compteur=0;
						robot.mousePress(InputEvent.BUTTON1_MASK);
						System.out.println("clique");
						robot.mouseRelease(InputEvent.BUTTON1_MASK);
					}
					
					x=(int)p.getX();
					y=(int)p.getY();
					
					robot.mouseMove((int)(Window.dimensionScreen.getWidth()-p.getX()), (int)p.getY());
				}
				try {
					Thread.sleep(10);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} catch (AWTException e) {
			System.out.println(e.getMessage());
		}

	}
	
	
	
	
}
